package xyz.labmem.app.unit

import cn.hutool.core.util.RandomUtil
import javafx.animation.KeyFrame
import javafx.animation.KeyValue
import javafx.animation.Timeline
import javafx.beans.property.SimpleBooleanProperty
import javafx.event.EventHandler
import javafx.geometry.Insets
import javafx.geometry.Pos
import javafx.scene.control.Label
import javafx.scene.image.ImageView
import javafx.scene.input.MouseEvent
import javafx.scene.layout.HBox
import javafx.scene.layout.Pane
import javafx.scene.layout.StackPane
import javafx.scene.layout.VBox
import javafx.scene.paint.Color
import javafx.scene.shape.Polygon
import javafx.util.Duration
import xyz.labmem.app.config.AppConfig.mouseImage
import xyz.labmem.app.config.AppConfig.uiImage
import xyz.labmem.app.dialog.form.ClientConfigForm
import xyz.labmem.app.main.CenterPane
import xyz.labmem.app.main.MainStage
import xyz.labmem.app.util.close
import xyz.labmem.app.util.mouseClickedPoll
import xyz.labmem.lipx.core.Type
import xyz.labmem.lipx.core.entity.ClientConfig
import xyz.labmem.lipx.core.tool.labVersion
import xyz.labmem.util.viewRun


class MenuUnit(parent: CenterPane) : VBox() {

    private val btnVBox = VBox()

    init {
        style = "-fx-background-color: rgba(255, 255, 255, 0.1);-fx-background-radius: 10;"
        this.prefHeightProperty().bind(parent.prefHeightProperty().subtract(50))
        this.prefWidth = 230.0
        btnVBox.alignment = Pos.CENTER_LEFT
        btnVBox.children.add(MenuBtn("首页") { it, _ ->
            groupCheck(it)
            parent.showHomePage()
        }.apply {
            MainStage.onFinishShow {
                Thread {
                    Thread.sleep(500)
                    viewRun {
                       this.toCheck(null)
                    }
                }.start()
            }
        })
        btnVBox.children.add(MenuBtn("代理服务") { it, _ ->
            groupCheck(it)
            parent.showServerPage()
        })
        btnVBox.children.add(MenuBtn("正向代理") { it, e ->
            if (e?.clickCount == 2) {
                MainStage.formDialog(ClientConfigForm("新增", ClientConfig().apply { type = Type.FORWARD }))
            } else {
                groupCheck(it)
                parent.showProxyUnit(it, Type.FORWARD)
            }
        })
        btnVBox.children.add(MenuBtn("反向代理") { it, e ->
            if (e?.clickCount == 2) {
                MainStage.formDialog(ClientConfigForm("新增", ClientConfig().apply { type = Type.REVERSE }))
            } else {
                groupCheck(it)
                parent.showProxyUnit(it, Type.REVERSE)
            }
        })
//        btnVBox.children.add(MenuBtn("设置") { it, _ ->
//            groupCheck(it)
//            parent.showSettingPage()
//        })
        val exitImage = ImageView(uiImage["exit"]).apply {
            fitWidth = 80.0
            isPreserveRatio = true
        }
        val exitLabel = LabelUnit(
            "EXIT",
            30.0,
            color = Color.BLACK,
            shadowColor = Color.RED,
            oColor = Color.RED,
            backColor = Color.BLACK
        )
        val exit = HBox(exitImage, exitLabel)
        val action = Timeline(
            KeyFrame(Duration.millis(150.0), { _ ->
                exitImage.rotate = RandomUtil.randomDouble(-10.0, 10.1)
            }),
            KeyFrame(Duration.millis(200.0), { _ -> exitLabel.refreshText() })
        )
        action.cycleCount = Timeline.INDEFINITE
        exit.onMouseEntered = EventHandler {
            MainStage.setCursor(mouseImage["m6"])
            action.play()
        }
        exit.onMouseExited = EventHandler {
            MainStage.cursorBack()
            action.stop()
        }
        exit.onMouseClicked = mouseClickedPoll {
            MainStage.confirmDialog("关闭LIPX", "要回去了吗？") {
                Thread {
                    MsgUnit.getMsgUnit().showMsg("再见~周卡")
                    Thread.sleep(1000)
                    parent.stage.scene.window.close()
                }.start()
                true
            }
        }
        setMargin(exit, Insets(.0, .0, 20.0, 30.0))
        getVgrow(exit)
        btnVBox.prefHeightProperty().bind(prefHeightProperty().subtract(exit.prefHeight))
        children.add(btnVBox)
        children.add(exit)
        children.add(Label("v$labVersion").apply {
            setMargin(this, Insets(.0, .0, 5.0, 180.0))
        })
    }

    private fun groupCheck(btn: MenuBtn) {
        btnVBox.children.forEach {
            if (it is MenuBtn && it != btn) {
                it.check.value = false
            }
        }
    }

}

class MenuBtn(text: String, private val checkFun: (MenuBtn, MouseEvent?) -> Unit) : Pane() {
    val check = SimpleBooleanProperty(false)
    private val background1: Polygon
    private val background2: Polygon
    private val background3: Polygon
    private val checkBackground: Polygon
    private val sword: ImageView
    private var offset1 = 0
    private var step1 = 1
    private var step1a = false
    private var step1b = false
    private var offset2 = 0
    private var step2 = 1
    private var step2a = false
    private var step2b = false
    private val with = 120
    private val x = 0.0
    private val y = -10.0
    private val textUnit: LabelUnit
    private val point1 = listOf(
        x, y,
        x + with + 30.0, y - 10,
        x + with, y + 30,
        x - 40.0, y + 30 + 12
    )
    private val point2 = listOf(
        x, y,
        x + with, y,
        x + with, y + 30,
        x, y + 30
    )
    private val swordTimeline: Timeline
    private val action = Timeline(
        KeyFrame(
            Duration.millis(10.0),
            { _ ->
                animate()
                animate2()
                animate3()
            }
        ),
    )

    init {
//        style = "-fx-border-color: red; -fx-border-width: 1px;"
        prefHeight = 50.0
        prefWidth = 230.0
//        clip = Rectangle(230.0, 50.0)
        sword = ImageView(uiImage["sword"]).apply {
            rotate = 45.0
            fitWidth = 40.0
            fitHeight = 81.0
            isVisible = false
        }
        VBox.setMargin(this, Insets(30.0, .0, .0, .0))
        val sp = StackPane().apply {
//            style = "-fx-border-color: green; -fx-border-width: 1px;"
            maxHeightProperty().bind(this@MenuBtn.prefHeightProperty())
            minHeightProperty().bind(this@MenuBtn.prefHeightProperty())
            maxWidthProperty().bind(this@MenuBtn.prefWidthProperty())
            minWidthProperty().bind(this@MenuBtn.prefWidthProperty())

            alignment = Pos.CENTER
            background1 = Polygon().apply {
                fill = Color.rgb(28, 254, 255)
            }
            background2 = Polygon().apply {
                fill = Color.rgb(255, 0, 34)
            }
            background3 = Polygon().apply {
                fill = Color.WHITE
            }
            checkBackground = Polygon().apply {
                fill = Color.WHITE
                points.setAll(
                    listOf(
                        0.0, -12.0,
                        50.0, -5.0,
                        140.0, -10.0,
                        130.0, 15.0,
                        150.0, 50.0,
                        50.0, 35.0,
                        0.0, 40.0,
                        10.0, 10.0,
                    )
                )
                isVisible = false
            }
            children.add(background1)
            children.add(background2)
            children.add(background3)
            children.add(checkBackground)
            textUnit = LabelUnit(text, 28.0)
            children.add(textUnit)

            action.cycleCount = Timeline.INDEFINITE
            onMouseEntered = EventHandler {
                MainStage.setCursor(mouseImage["m6"])
                if (!check.value) {
                    step1 = 1
                    step2 = 1
                    offset1 = 20
                    offset2 = 0
                    background1.points.setAll(point1)
                    background2.points.setAll(point2)
                    background3.points.setAll(point2)
                    background1.isVisible = true
                    background2.isVisible = true
                    background3.isVisible = true
                    checkBackground.isVisible = false
                    sword.isVisible = false
                    Thread {
                        Thread.sleep(100)
                        action.play()
                    }.start()
                }
            }

            onMouseExited = EventHandler {
                stopAction()
            }
            onMouseClicked = mouseClickedPoll {
                toCheck(it)
            }
        }
        children.add(sp)
        children.add(sword)
        check.addListener { _, _, v ->
            checkBackground.isVisible = v
            sword.isVisible = v
        }
        swordTimeline = Timeline()
    }

    private fun stopAction() {
        MainStage.cursorBack()
        action.stop()
        background1.isVisible = false
        background2.isVisible = false
        background3.isVisible = false
    }

    fun toCheck(it: MouseEvent?) {
        check.value = true
        stopAction()
        makeSword {
            textUnit.refreshText()
            checkFun(this@MenuBtn, it)
        }
    }

    private fun animate() {
        // 控制扭动的逻辑
        if (step1 == 1) {
            offset1 -= 1
            if (step1a) {
                background1.points[2] -= 2.0
                background1.points[3] += .6
                background1.points[6] += 1.5
                background1.points[7] -= .5
            } else {
                background1.points[2] -= 1.5
                background1.points[3] += .5
                background1.points[6] += 2.0
                background1.points[7] -= .6
            }
            if (offset1 <= 0) {
                step1 = 2
                step1a = !step1a
            }
        } else if (step1 == 2) {
            offset1 += 1
            if (step1b) {
                background1.points[4] += 1.8
                background1.points[5] += .5
                background1.points[0] -= 1.5
                background1.points[1] -= .2
            } else {
                background1.points[4] += 1.5
                background1.points[5] += .2
                background1.points[0] -= 1.8
                background1.points[1] -= .5
            }
            if (offset1 >= 20) {
                step1 = 3
            }
        } else if (step1 == 3) {
            offset1 -= 1
            if (step1b) {
                background1.points[4] -= 1.8
                background1.points[5] -= .5
                background1.points[0] += 1.5
                background1.points[1] += .2
            } else {
                background1.points[4] -= 1.5
                background1.points[5] -= .2
                background1.points[0] += 1.8
                background1.points[1] += .5
            }
            if (offset1 <= 0) {
                step1 = 4
                step1b = !step1b
            }
        } else if (step1 == 4) {
            offset1 += 1
            if (offset1 >= 20) {
                step1 = 1
            }
            if (step1a) {
                background1.points[2] += 2.0
                background1.points[3] -= .6
                background1.points[6] -= 1.5
                background1.points[7] += .5
            } else {
                background1.points[2] += 1.5
                background1.points[3] -= .5
                background1.points[6] -= 2.0
                background1.points[7] += .6
            }

        }

    }


    private fun animate2() {
        // 控制扭动的逻辑
        if (step2 == 1) {
            offset2 += 1
            if (offset2 >= 20) {
                step2 = 2
            }
            if (step2a) {
                background2.points[4] += 1.5
                background2.points[5] += .25
                background2.points[0] -= 1.2
                background2.points[1] -= .3
            } else {
                background2.points[4] += 1.2
                background2.points[5] += .3
                background2.points[0] -= 1.5
                background2.points[1] -= .25
            }

        } else if (step2 == 2) {
            offset2 -= 1
            if (step2a) {
                background2.points[4] -= 1.5
                background2.points[5] -= .25
                background2.points[0] += 1.2
                background2.points[1] += .3
            } else {
                background2.points[4] -= 1.2
                background2.points[5] -= .3
                background2.points[0] += 1.5
                background2.points[1] += .25
            }
            if (offset2 <= 0) {
                step2 = 3
                step2a = !step2a
            }

        } else if (step2 == 3) {
            offset2 += 1
            if (offset2 >= 20) {
                step2 = 4
            }
            if (step2b) {
                background2.points[2] += 1.3
                background2.points[3] -= .3
                background2.points[6] -= 1.0
                background2.points[7] += .25
            } else {
                background2.points[2] += 1.0
                background2.points[3] -= .25
                background2.points[6] -= 1.3
                background2.points[7] += .3
            }

        } else if (step2 == 4) {
            offset2 -= 1
            if (step2b) {
                background2.points[2] -= 1.3
                background2.points[3] += .3
                background2.points[6] += 1.0
                background2.points[7] -= .25
            } else {
                background2.points[2] -= 1.0
                background2.points[3] += .25
                background2.points[6] += 1.3
                background2.points[7] -= .3
            }
            if (offset2 <= 0) {
                step2 = 1
                step2b = !step2b
            }
        }
    }

    private fun animate3() {
        if (background1.points[0] > background2.points[0]) {
            background3.points[0] = background1.points[0] + 5
            background3.points[1] = background1.points[1] + 5
        } else {
            background3.points[0] = background2.points[0] + 5
            background3.points[1] = background2.points[1] + 5
        }
        if (background1.points[2] > background2.points[2]) {
            background3.points[2] = background2.points[2]
            background3.points[3] = background2.points[3]
        } else {
            background3.points[2] = background1.points[2]
            background3.points[3] = background1.points[3]
        }
        if (background1.points[4] > background2.points[4]) {
            background3.points[4] = background2.points[4] - 5
            background3.points[5] = background2.points[5] - 5
        } else {
            background3.points[4] = background1.points[4] - 5
            background3.points[5] = background1.points[5] - 5
        }
        if (background1.points[6] > background2.points[6]) {
            background3.points[6] = background1.points[6]
            background3.points[7] = background1.points[7]
        } else {
            background3.points[6] = background2.points[6]
            background3.points[7] = background2.points[7]
        }
    }


    private fun makeSword(f: () -> Unit) {
        sword.layoutX = 230.0
        sword.layoutY = -80.0
        sword.translateX = .0
        checkBackground.scaleX = 0.1
        checkBackground.scaleY = 0.1
        swordTimeline.keyFrames.setAll(
            KeyFrame(Duration.millis(100.0), KeyValue(sword.layoutXProperty(), 170)),
            KeyFrame(Duration.millis(100.0), KeyValue(sword.layoutYProperty(), -20)),
            KeyFrame(Duration.millis(200.0), KeyValue(checkBackground.scaleXProperty(), 1)),
            KeyFrame(Duration.millis(200.0), KeyValue(checkBackground.scaleYProperty(), 1)),
        )
        swordTimeline.onFinished = EventHandler {
            f()
        }
        swordTimeline.play()
    }

}